<?php
/**
 * @author  lifeibest@gmail.com
 *  simple use with little code, we are less but do more
 */
class Phpmongo
{
	public  $_mongo;
	public  $_db;
	public  $db;
	public $_collection;
	public $collection;
	public $_noPk = false;
	public $_count;
	
	static private $_instance=null;	
	
	function __construct ($db = '', $collection =''){
		if(!self::$_instance){
			self::$_instance= $this->connect();
		}
		$this->_mongo = self::$_instance;
		
		// this for query
		if ($db && $collection){
			$this->db = $db;
			$this->_db = $this->_mongo->selectDb($db);
			$this->_collection = $this->_db->selectCollection($collection);
			$this->collection = $collection;
		}
	}	
	
	function connect(){
		return  new Mongo("127.0.0.1:27017");
	}
	
	/**
	 *
	 * @param unknown_type $db
	 * @return unknown
	 * @link http://us2.php.net/manual/en/mongo.selectdb.php
	 */
	function selectDb($db){
		$db = trim($db);
		if ($db){
			return $this->_mongo->selectDb($db);
		} else{
			return ;
		}
	}
	
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $collection
	 * @return unknown
	 * @link http://us2.php.net/manual/en/mongo.selectcollection.php
	 */
	function selectCollection($collection){
		return $this->_db->selectCollection($collection);
	}
	

	/**
	 * All strings sent to the database must be UTF-8. If a string is not UTF-8, 
	 * a MongoException will be thrown. To insert (or query for) a non-UTF-8 string, use MongoBinData. 
	 *
	 * @param unknown_type $arr
	 * @param unknown_type $option    safe or  fsync
	 * @link http://us2.php.net/manual/en/mongocollection.insert.php
	 */
	function insert($arr, $option = array()){
		$arr = $this->stringToArray($arr);
		return $this->_collection->insert($arr, $option);
	}
	
	function update($criteria, $newobj, $options = array() ){
		$newobj = $this->stringToArray($newobj);
		return $this->_collection->update($criteria, $newobj, $options);
	}
	

	
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $criteria
	 * @param unknown_type $options
	 * @link http://us2.php.net/manual/en/mongocollection.remove.php
	 */
	function remove($criteria = array(),$options = array()){
		return $this->_collection->remove($criteria, $options);
	}
	
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $query
	 * @param unknown_type $fields
	 * @link http://us2.php.net/manual/en/mongocollection.find.php
	 */
	function find( $query = array(), $fields = array()){
		return $this->_collection->find($query, $fields);
	}
	
	
	function query($query, $option = array()){
		
		$skip = $option['skip'];
		$limit = $option['limit'];
		$cursor = $this->_collection->find($query);
		$this->_count = $cursor->count();
		$cursor->skip($skip);
		$cursor->limit($limit);
		return  objectToArray($cursor);		
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $query
	 * @param unknown_type $fields
	 * @return unknown
	 * @link http://us2.php.net/manual/en/mongocollection.findone.php
	 */
	function findOne( $query = array(), $fields = array()){
		return $this->_collection->findOne($query, $fields);
	}
	
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $arr
	 * @return unknown
	 * @link http://us2.php.net/manual/en/mongocollection.find.php
	 */
	function findAll($arr = array()){
		$cursor = $this->_collection->find($arr);
		return objectToArray($cursor);
	}
	
	
	function findById($id){
		$row =  $this->_collection->findOne(array('_id' => new MongoId($id)));
		$row['_id'] = $row['_id']->__toString();
		return $row;
	}
	
	/**
	 *
	 * @param unknown_type $returnPk
	 * @return RQuery
	 */
	function noPk($noPk = true) {
		$this->_noPk = $noPk;
		return $this->_noPk;
	}	

	/**
	 * Create new db
	 *
	 * @param unknown_type $dbname
	 * @link http://us2.php.net/manual/en/mongo.selectdb.php
	 */
	function createDb($dbname){
		$dbname = trim($dbname);
		$this->_mongo->selectDb($dbname)->execute("function(){}");
	}
	
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $dbname
	 * @return unknown
	 * @link http://us2.php.net/manual/en/mongo.dropdb.php
	 */
	function dropDb($dbname){
		return $this->_mongo->dropDB($dbname);
	}
	
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $arr
	 * @link http://us2.php.net/manual/en/mongodb.createcollection.php
	 */
	function createCollection($arr){
		$db = $arr['db'];
		$collection = trim($arr['collection']);
		$capped = $arr['capped'];
		if ($capped == 1){
			$capped = true;
		} else{
			$capped = false;
		}
		$size = intval($arr['size']);
		$max = intval($arr['max']);
		$this->_db = $this->selectDb($db);
		$this->_db->createCollection($collection, $capped, $size, $max);
	}
	
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $db
	 * @param unknown_type $collection
	 * @link http://us2.php.net/manual/en/mongodb.dropcollection.php
	 */
	function dropCollection($db, $collection){
		$_db = $this->selectDb($db);
		$_db->dropCollection($collection);		
	}
	
	/**
	 * Remove records from this collection
	 *
	 * @param unknown_type $db
	 * @param unknown_type $collection
	 * @link http://us2.php.net/manual/en/mongocollection.remove.php
	 */
	function clearCollection($db, $collection){
		$_db = $this->selectDb($db);
		$_collection = $_db->$collection;
		$_collection->remove();
	}
	
	
	/**
	 * all database 
	 *
	 * @return unknown
	 * @link http://us2.php.net/manual/en/mongo.listdbs.php
	 */
	function dbList(){
		$listDBs = $this->_mongo->listDBs();
		$databases = $listDBs['databases']; 
		$databases = Helper_Array::sortByCol($databases, 'name');
		return $databases;
	}
	
	/**
	 * the amount of collection
	 *
	 * @param unknown_type $db
	 * @return unknown
	 */
	function countCollection($db){
		return count($this->getCollection($db));
	}	
	/**
	 * get collections
	 *
	 * @param unknown_type $db
	 * @return unknown
	 * @link  http://us2.php.net/manual/en/mongodb.listcollections.php
	 */
	function getCollection($db){
		$this->_db = $this->selectDb($db);
		if (!$this->_db) return ;
		$list = $this->_db->listCollections();
		$tables = array();
		foreach ($list as $collection){
			$tables[] = $collection->getName();
		}
		sort($tables);
		return $tables;
	}

	/**
	 * database info
	 *
	 * @return unknown
	 */
	function databaseInfo(){
		$dbs = $this->dbList();
		$dataInfo = array();
		foreach ($dbs as $db){
			$mongodb = $this->selectDb($db['name']);
			$info = $mongodb->command(array("dbstats" => 1));
			$info['name'] = $db['name'];
			$dataInfo[] = $info;
		}
		return $dataInfo;
	}
	
	/**
	 * collection info
	 *
	 */
	function collectionInfo($db, $collection){
		$_db = $this->selectDb($db);
		$ret = $_db->execute("db.$collection.stats()");
		if ($ret["ok"]) {
			return  $ret["retval"];
		}
	}
	
	
	function stringToArray($data){
		$data = $data . ";";  
		$row = null;
		if (@eval("\$row=" . $data . ";") === false || !is_array($row)) {
			message("Only array is accepted", "collection.php?db=$this->db&collection=$this->collection");
		}
		return $row;
	}
}



?>